package com.solidumgame.martillo
{
	import Box2D.Dynamics.Joints.b2Joint;
	import Box2D.Dynamics.b2Body;
	
	import com.greensock.TweenMax;
	import com.pblabs.box2D.Box2DDebugComponent;
	import com.pblabs.box2D.Box2DManagerComponent;
	import com.pblabs.engine.PBE;
	import com.pblabs.engine.debug.Logger;
	import com.pblabs.engine.entity.EntityComponent;
	import com.pblabs.engine.entity.IEntity;
	import com.pblabs.rendering2D.SpriteRenderer;
	import com.pblabs.rendering2D.ui.SceneView;
	import com.solidumgame.martillo.background.Background;
	import com.solidumgame.martillo.events.MatchGenericEvent;
	import com.solidumgame.martillo.hammer.Hammer;
	import com.solidumgame.martillo.health.Health;
	import com.solidumgame.martillo.health.events.HealthGenericEvent;
	import com.solidumgame.martillo.level.Level;
	import com.solidumgame.martillo.nail.Nail;
	import com.solidumgame.martillo.nail.events.NailGenericEvent;
	import com.solidumgame.martillo.score.Score;
	import com.solidumgame.martillo.score.events.ScoreGenericEvent;
	import com.solidumgame.martillo.tablewood.TableWood;
	import com.solidumgame.martillo.tablewood.events.TableWoodGenericEvent;
	import com.solidumgame.martillo.utils.RandomGenerator;
	
	import flash.events.EventDispatcher;
	import flash.geom.Point;

	public class Match extends EventDispatcher
	{

		protected var hammer:Hammer;
		protected var currentTableWood:TableWood;
		protected var currentLevel:int = 1;
		protected var currentNails:Vector.<Nail>;
		protected var houseHealth:Health;
		protected var level:Level;
		protected var score:Score;
		protected var box2DManager:IEntity;
		protected var box2DDebugger:IEntity;
		protected static var sceneView:SceneView;
		
		protected var fondo:Background;
		
		public var finalScore:Number = 0;
		
		public function Match():void
		{
			createScene();
			createBox2DManager();
			createBox2DDebugger();			
			initSingleElements();
			newMatch();
			
		}
		
		protected function initSingleElements():void{
			hammer = new Hammer();
			houseHealth = new Health();
			score = new Score();
			level = new Level();
			fondo = new Background();
			
			PBE.mainStage.addEventListener(HealthGenericEvent.HEALTH_ZERO_EVENT, finishGame);
		}
		
		private function newMatch():void{
			currentTableWood = new TableWood();
			currentTableWood.addEventListener(TableWoodGenericEvent.TABLEWOOD_ENTER_EVENT, tableWoodInPosition);
			
			PBE.mainStage.addEventListener(ScoreGenericEvent.SCORE_UPDATED_EVENT,updateFinalScore);
		}
		
		private function tableWoodInPosition(e:TableWoodGenericEvent):void{
			currentTableWood.removeEventListener(TableWoodGenericEvent.TABLEWOOD_ENTER_EVENT, tableWoodInPosition);
			currentNails = new Vector.<Nail>();
			generateNails(int(RandomGenerator.getRandom()*5+1));
		}
		
		private function finishMatch(e:TableWoodGenericEvent):void{
			

			
			currentTableWood.removeEventListener(TableWoodGenericEvent.TABLEWOOD_EXIT_EVENT, finishMatch);

			for each (var nail:Nail in currentNails) 
			{
				nail.remove();
			}

			currentTableWood.remove();
			
			newMatch();
		}
		
		
		private function updateFinalScore(e:ScoreGenericEvent):void{
			finalScore = e.score;
		}
		
		private function finishGame(e:HealthGenericEvent):void{
			
			PBE.mainStage.removeEventListener(HealthGenericEvent.HEALTH_ZERO_EVENT, finishGame);			
			
			for each (var nail:Nail in currentNails) 
			{
				nail.remove();
			}
			
			hammer.remove();
			currentTableWood.remove();
			score.remove();
			houseHealth.remove();
			box2DManager.destroy();
			box2DDebugger.destroy();
			
			currentNails = null;
			hammer = null;
			currentTableWood = null;
			score = null;
			houseHealth = null;
			box2DManager = null;
			box2DDebugger = null;
			
			this.dispatchEvent(new MatchGenericEvent(MatchGenericEvent.MATCH_END_EVENT,finalScore));
		}
		
		private function generateNails(i:int):void{
			if(i){
				var rand:Number = RandomGenerator.getRandom()*250;
				
				var type:Number = RandomGenerator.getRandom();
				
				if(type <0.33)
					type = Nail.SIZE_SMALL;
				else if (type <0.66)
					type = Nail.SIZE_MEDIUM;
				else
					type = Nail.SIZE_LARGE;
				var nail:Nail = new Nail(new Point(-125+rand,-200+rand),type);
				
				nail.addEventListener(NailGenericEvent.NAIL_NAILED_EVENT, onNailNailed);
				nail.addEventListener(NailGenericEvent.NAIL_NOT_NAILED_EVENT, onNailNailed);
				currentNails.push(nail);
				
				var delay:Number = RandomGenerator.getRandom()*0.5+0.1;
				
				TweenMax.delayedCall(delay,generateNails,[--i]);
			}
		}
		
		protected function onNailNailed(e:NailGenericEvent):void{
						
			var areAllNailed:Boolean = true;
			for each (var nail:Nail in currentNails) 
			{
				areAllNailed &&= nail.isNailed;
			}
		
			if(areAllNailed){
				currentTableWood.addEventListener(TableWoodGenericEvent.TABLEWOOD_EXIT_EVENT, finishMatch);
				currentTableWood.throwOutTableWood();
			}
		}

		
		private function createBox2DDebugger():void {
			// Create debugger component.
			var comp:Box2DDebugComponent = new Box2DDebugComponent();
			comp.spatialManager = PBE.lookupEntity("SpatialManager").lookupComponentByName("Manager") as Box2DManagerComponent;
			comp.scene = PBE.scene;
			
			// Allocate new entity and add components.
			box2DDebugger = PBE.allocateEntity();
			box2DDebugger.addComponent(comp, "Debug");
			box2DDebugger.initialize("SpatialDebugger");
		}
		
		
		
		private function createScene():void {
			if(sceneView==null){
				sceneView = new SceneView();
				sceneView.width = 640;
				sceneView.height = 480;
				PBE.initializeScene(sceneView);
			}
		}
		
		private function createBox2DManager():void {
			
			var comp:Box2DManagerComponent = new Box2DManagerComponent();

			box2DManager = PBE.allocateEntity();
			box2DManager.addComponent(comp, "Manager");
			box2DManager.initialize("SpatialManager");
		}
		
	}
}